import axios, {
    type AxiosInstance,
    type AxiosRequestConfig,
    type AxiosResponse,
    type InternalAxiosRequestConfig
} from 'axios'

import {ElMessage} from 'element-plus'
import router from '@/router'
import {useUserStore} from '@/stores/user.ts'

// 定义请求响应的数据结构类型
export interface ResponseData<T = any> {
    code: number
    data: T
    message: string
}

// 创建axios实例
const service: AxiosInstance = axios.create({
    baseURL: import.meta.env.VITE_API_BASE_URL || '',
    timeout: 15000,
    headers: {
        'Content-Type': 'application/json;charset=utf-8'
    }
})

// 请求拦截器
service.interceptors.request.use(
    (config: InternalAxiosRequestConfig) => {
        // 在发送请求前做一些处理
        const userStore = useUserStore()
        const token = userStore.token

        // 如果token存在，在请求头中添加token
        if (token) {
            if (config.headers) {
                config.headers['Authorization'] = `Bearer ${token}`
            }
        }

        return config
    },
    (error) => {
        // 对请求错误做些什么
        console.error('请求错误:', error)
        return Promise.reject(error)
    }
)

// 响应拦截器
service.interceptors.response.use(
    (response: AxiosResponse<ResponseData>) => {
        const res = response.data

        // 根据响应的状态码进行处理
        // 这里假设后端返回的code为200表示成功
        if (res.code !== 200) {
            ElMessage({
                message: res.message || '请求失败',
                type: 'error',
                duration: 5 * 1000
            })

            // 处理特定的错误码
            if (res.code === 401) {
                // token过期或未认证
                const userStore = useUserStore()
                userStore.logout()
                router.replace('/admin/login')
            }

            return Promise.reject(new Error(res.message || '请求失败'))
        } else {
            // 返回原始响应以匹配类型要求
            return response
        }
    },
    (error) => {
        console.error('响应错误:', error)

        // 处理HTTP错误状态码
        if (error.response) {
            const status = error.response.status

            switch (status) {
                case 401:
                    ElMessage({
                        message: '未授权，请重新登录',
                        type: 'error',
                        duration: 5 * 1000
                    })
                    // 清除token并跳转到登录页
                    const userStore = useUserStore()
                    userStore.logout()
                    router.replace('/admin/login')
                    break
                case 403:
                    ElMessage({
                        message: '拒绝访问',
                        type: 'error',
                        duration: 5 * 1000
                    })
                    break
                case 404:
                    ElMessage({
                        message: '请求的资源不存在',
                        type: 'error',
                        duration: 5 * 1000
                    })
                    break
                case 500:
                    ElMessage({
                        message: '服务器错误',
                        type: 'error',
                        duration: 5 * 1000
                    })
                    break
                default:
                    ElMessage({
                        message: error.message || '请求失败',
                        type: 'error',
                        duration: 5 * 1000
                    })
            }
        } else {
            ElMessage({
                message: '网络异常，请检查您的网络连接',
                type: 'error',
                duration: 5 * 1000
            })
        }

        return Promise.reject(error)
    }
)

// 封装GET请求
export function get<T = any>(url: string, params?: any, config?: AxiosRequestConfig): Promise<ResponseData<T>> {
    return service.get(url, {params, ...config}).then(res => res.data)
}

// 封装POST请求
export function post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<ResponseData<T>> {
    return service.post(url, data, config).then(res => res.data)
}

// 封装PUT请求
export function put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<ResponseData<T>> {
    return service.put(url, data, config).then(res => res.data)
}

// 封装DELETE请求
export function del<T = any>(url: string, config?: AxiosRequestConfig): Promise<ResponseData<T>> {
    return service.delete(url, config).then(res => res.data)
}

// 导出axios实例
export default service 